package top.zhouze.common.base;

import android.annotation.SuppressLint;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import lombok.Getter;
import lombok.SneakyThrows;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

public abstract class BaseAdapter<T,V extends ViewBinding> extends RecyclerView.Adapter<BaseHolder<V>> {
    private final String TAG = getClass().getSimpleName();

    @Getter
    protected List<T> data;

    public BaseAdapter() {
        this.data = new ArrayList<>();
    }

    protected BaseAdapter(List<T> data) {
        this.data = data;
    }

    protected BaseAdapter(T t) {
        this.data = new ArrayList<>();
        data.add(t);
    }

    @NonNull
    @Override
    public BaseHolder<V> onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new BaseHolder<>(onBindingView(viewGroup));
    }
 
    @Override
    public void onBindViewHolder(@NonNull BaseHolder<V> holder, int position) {
        onBindingData(holder,data.get(position),position);
    }

    protected abstract void onBindingData(BaseHolder<V> holder, T t, int position);
//    protected abstract V onBindingView(ViewGroup viewGroup);

    @SneakyThrows
    @SuppressWarnings("unchecked")
    protected V onBindingView(ViewGroup viewGroup) {
        ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
        Class<V> vmCls = (Class<V>) Objects.requireNonNull(type).getActualTypeArguments()[1];
        Method method = vmCls.getDeclaredMethod("inflate", LayoutInflater.class);
        return  (V) method.invoke(null, LayoutInflater.from(viewGroup.getContext()));
    }

    @Override
    public int getItemCount() {
        return data==null?0:data.size();
    }

    public boolean addItem(T t){
        boolean isAdd = data.add(t);
        this.notifyItemInserted(data.size());
        return isAdd;
    }

    public boolean contains(T t){
        return data.contains(t);
    }

    public void addItem(Collection<T> itemData){
        data.addAll(itemData);
        this.notifyItemInserted(data.size());
    }

    public void updateItem(T t,int position){
        if (inRange(position)) {
            data.set(position,t);
            this.notifyItemChanged(position);
        } else {
            Log.w(TAG,"position is out of range");
        }
    }

    public void updateItem(T t){
        updateItem(t, data.indexOf(t));
    }

    public void removeItem(int position){
        if (inRange(position)) {
            data.remove(position);
            //删除动画
            notifyItemRemoved(position);
            notifyItemRangeChanged(position,data.size()-position);
        }else {
            Log.w(TAG,"position is out of range");
        }
    }

    public void removeItem(T t){
        removeItem(data.indexOf(t));
    }

    private boolean inRange(int position){
        return position>=0 && position<data.size();
    }

    @SuppressLint("NotifyDataSetChanged")
    public void clear(){
        if (!data.isEmpty()) {
            data.clear();
            notifyDataSetChanged();
        }
    }

    public int size(){
        return data.size();
    }

    public boolean isEmpty(){
        return data.isEmpty();
    }

    /**
     * 设置线性布局
     *
     * @param recyclerView 回收器视图
     */
    public void setLinearLayout(RecyclerView recyclerView) {
        //这里用线性显示 类似于listview
        recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
        recyclerView.setAdapter(this);
    }

    /**
     * 设置倒序线性布局
     *
     * @param recyclerView 回收器视图
     */
    public void setDescLinearLayout(RecyclerView recyclerView) {
        LinearLayoutManager layout = new LinearLayoutManager(recyclerView.getContext());
        //列表再底部开始展示，反转后由上面开始展示
        layout.setStackFromEnd(true);
        //列表翻转
        layout.setReverseLayout(true);
        recyclerView.setLayoutManager(layout);
        recyclerView.setAdapter(this);
    }

    public void scrollToTop(RecyclerView recyclerView) {
        recyclerView.scrollToPosition(getItemCount() - 1);
    }
}